﻿using System;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;

namespace Nirvana
{

	internal sealed class PoolProfilterWindow : EditorWindow
	{


		private string mSearch;


		private bool mAssetCache = true;


		private bool mObjectCache = true;


		private bool mPrefabCache = true;

        private bool mAudioClipCache = true;
        private bool mScriptableCache = true;

		private bool mFontCache = true;
        private bool mSpriteCache = true;
        private bool mTextureCache = true;
   
        private Vector2 startPos;

		[MenuItem("Nirvana/Pool Profilter Window", false)]
		internal static void Init()
		{
			Rect rect = new Rect(0f, 0f, 800f, 800f);
            PoolProfilterWindow windowWithRect = EditorWindow.GetWindowWithRect<PoolProfilterWindow>(rect, false, "Pool Profilter Window");
			windowWithRect.Show();
		}


		private void OnEnable()
		{
			base.hideFlags = HideFlags.HideAndDontSave;
		}


		private void OnFocus()
		{
			this.Repaint();
		}


		private void OnSelectionChange()
		{
			this.Repaint();
		}

		private void OnGUI()
		{
			GUILayout.Space(10f);
			EditorGUILayout.LabelField("Pool Profilter Window", GUITheme.LabelTitleStyle, new GUILayoutOption[0]);
			GUILayout.Space(10f);
			if (!Application.isPlaying)
			{
				EditorGUILayout.HelpBox("The pool window is only valid when the game is playing.",  MessageType.Info);
				return;
			}
			this.startPos = GUILayout.BeginScrollView(this.startPos, new GUILayoutOption[0]);
			this.mSearch = EditorGUILayout.TextField("Search:", this.mSearch, new GUILayoutOption[0]);
			this.DrawBaseUI();
			this.DrawPrefabCacheUI();
            this.DrawSpriteCacheUI();
            this.DrawTextureCacheUI();
			this.DrawAudioClipCacheUI();
            this.DrawScriptableCacheUI();
			this.DrawFontCacheUI();
			GUILayout.EndScrollView();
		}


		private bool IsFoldOut(string title, ref bool onFold)
		{
			if (!string.IsNullOrEmpty(this.mSearch))
			{
				return true;
			}
            onFold = EditorGUILayout.Foldout(onFold, title);
			return onFold;
		}


		private bool IsSearch(string txt)
		{
			return string.IsNullOrEmpty(this.mSearch) || txt.Contains(this.mSearch);
		}

		private void DrawBaseUI()
		{
			GameObjectPool instance = GameObjectPool.Instance;
			if (this.IsFoldOut("Asset Cache", ref this.mAssetCache))
			{
				if (string.IsNullOrEmpty(this.mSearch) && instance.AssetCahces.Count == 0)
				{
					EditorGUILayout.HelpBox("There is no asset in this cache.",  MessageType.Info);
				}
				foreach (KeyValuePair<AssetID, GameObjectCache> keyValuePair in instance.AssetCahces)
				{
					this.DrawAssetCache(keyValuePair.Key, keyValuePair.Value);
				}
			}
			if (this.IsFoldOut("Object Cache", ref this.mObjectCache))
			{
				if (string.IsNullOrEmpty(this.mSearch) && instance.ObjectCaches.Count == 0)
				{
					EditorGUILayout.HelpBox("There is no object in this cache.",  MessageType.Info);
				}
				foreach (KeyValuePair<GameObject, GameObjectCache> keyValuePair2 in instance.ObjectCaches)
				{
					this.DrawObjectCache(keyValuePair2.Key, keyValuePair2.Value);
				}
			}
		}


		private void DrawPrefabCacheUI()
		{
			PrefabPool instance = PrefabPool.Instance;
			if (this.IsFoldOut("Prefab Cache", ref this.mPrefabCache))
			{
				if (string.IsNullOrEmpty(this.mSearch) && instance.GetCacheAssetIDMap().Count == 0)
				{
					EditorGUILayout.HelpBox("There is no prefab in this cache.", MessageType.Info);
				}
				foreach (KeyValuePair<AssetID, PrefabCache> keyValuePair in instance.GetCacheAssetIDMap())
				{
					this.DrawPrefabCache(keyValuePair.Key, keyValuePair.Value);
				}
			}
		}


		private void DrawScriptableCacheUI()
		{

		}




		private void DrawFontCacheUI()
		{

		}


		private void DrawAssetCache(AssetID assetid, GameObjectCache cache)
		{
			if (!this.IsSearch(assetid.BundleName) && !this.IsSearch(assetid.AssetName))
			{
				return;
			}
			GUILayoutEx.BeginContents();
			EditorGUILayout.LabelField(assetid.ToString(), new GUILayoutOption[0]);
			if (!string.IsNullOrEmpty(cache.Error))
			{
				Color color = GUI.color;
				GUI.color = Color.red;
				EditorGUILayout.LabelField(cache.Error, new GUILayoutOption[0]);
				GUI.color = color;
			}
			else
			{
				string text = string.Format("Spawned/Cached/PoolCount: {0}/{1}/{2}", cache.SpawnCount, cache.CacheCount, cache.maxPoolCacheCount);
				EditorGUILayout.LabelField(text, new GUILayoutOption[0]);
				string text2 = string.Format("Release after free: {0}", cache.ReleaseAfterFree);
				EditorGUILayout.LabelField(text2, new GUILayoutOption[0]);
				EditorGUI.indentLevel = 1;
				foreach (var cacheItem in cache.PoolCacheList)
				{
					EditorGUILayout.BeginHorizontal(new GUILayoutOption[0]);
					EditorGUILayout.ObjectField(GUIContent.none, cacheItem.CacheObject, cacheItem.CacheObject.GetType(), true, new GUILayoutOption[]
					{
						GUILayout.ExpandWidth(false)
					});
					float num = Time.realtimeSinceStartup - cacheItem.LastFreeTime;
					float num2 = cache.ReleaseAfterFree - num;
					float value = num2 / cache.ReleaseAfterFree;
					string text3 = string.Format("Left Sweep Time: {0:N2}", num2);
					GUILayoutEx.ProgressBar(value, text3);
					EditorGUILayout.EndHorizontal();
				}
				EditorGUI.indentLevel = 0;
			}
			GUILayoutEx.EndContents();
		}


		private void DrawObjectCache(GameObject go, GameObjectCache cache)
		{
			if (go == null || !this.IsSearch(go.name))
			{
				return;
			}
			GUILayoutEx.BeginContents();
			if (!string.IsNullOrEmpty(cache.Error))
			{
				Color color = GUI.color;
				GUI.color = Color.red;
				EditorGUILayout.BeginHorizontal(new GUILayoutOption[0]);
				EditorGUILayout.ObjectField("Asset: ", go, typeof(GameObject), false, new GUILayoutOption[0]);
				EditorGUILayout.LabelField(cache.Error, new GUILayoutOption[0]);
				EditorGUILayout.EndHorizontal();
				GUI.color = color;
			}
			else
			{
				EditorGUILayout.BeginHorizontal(new GUILayoutOption[0]);
				EditorGUILayout.ObjectField("Asset: ", go, typeof(GameObject), false, new GUILayoutOption[0]);
				string text = string.Format("Spawned/Cached/PoolCount: {0}/{1}/{2}", cache.SpawnCount, cache.CacheCount, cache.maxPoolCacheCount);
				EditorGUILayout.LabelField(text, new GUILayoutOption[0]);
				EditorGUILayout.EndHorizontal();
				string text2 = string.Format("Release after free: {0}", cache.ReleaseAfterFree);
				EditorGUILayout.LabelField(text2, new GUILayoutOption[0]);
				foreach (var cacheItem in cache.PoolCacheList)
				{
					EditorGUILayout.BeginHorizontal(new GUILayoutOption[0]);
					EditorGUILayout.ObjectField(GUIContent.none, cacheItem.CacheObject, cacheItem.CacheObject.GetType(), true, new GUILayoutOption[]
					{
						GUILayout.ExpandWidth(false)
					});
					float num = Time.realtimeSinceStartup - cacheItem.LastFreeTime;
					float num2 = cache.ReleaseAfterFree - num;
					float value = num2 / cache.ReleaseAfterFree;
					string text3 = string.Format("Left Sweep Time: {0:N2}", num2);
					GUILayoutEx.ProgressBar(value, text3);
					EditorGUILayout.EndHorizontal();
				}
			}
			GUILayoutEx.EndContents();
		}


		private void DrawPrefabCache(AssetID assetid, PrefabCache cache)
		{
			if (!this.IsSearch(assetid.BundleName) && !this.IsSearch(assetid.AssetName))
			{
				return;
			}
			GUILayoutEx.BeginContents();
			if (!string.IsNullOrEmpty(cache.Error))
			{
				Color color = GUI.color;
				GUI.color = Color.red;
				string text = string.Format("{0}: {1}", assetid, cache.Error);
				EditorGUILayout.LabelField(text, new GUILayoutOption[0]);
				GUI.color = color;
			}
			else
			{
				string text2 = string.Format("{0} (used: {1})", assetid, cache.ReferenceCount);
				EditorGUILayout.LabelField(text2, new GUILayoutOption[0]);
				if (cache.ReferenceCount <= 0)
				{
					float num = Time.realtimeSinceStartup - cache.LastFreeTime;
					float num2 = cache.ReleaseAfterFree - num;
					float value = num2 / cache.ReleaseAfterFree;
					string text3 = string.Format("Left Sweep Time: {0:N2}", num2);
					GUILayoutEx.ProgressBar(value, text3);
				}
			}
			GUILayoutEx.EndContents();
		}


        private void DrawSpriteCacheUI()
        {
            SpritePool instance = SpritePool.Instance;
            if (this.IsFoldOut("Sprite Cache", ref this.mSpriteCache))
            {
                if (string.IsNullOrEmpty(this.mSearch) && instance.GetCacheAssetIDMap().Count == 0)
                {
                    EditorGUILayout.HelpBox("There is no Sprite in this cache.", MessageType.Info);
                }
                foreach (var p in instance.GetCacheAssetIDMap())
                {
                    this.DrawSpriteCache(p.Key, p.Value);
                }
            }
        }
        private void DrawSpriteCache(AssetID assetid, SpriteCache cache)
        {
            if (!this.IsSearch(assetid.BundleName) && !this.IsSearch(assetid.AssetName))
            {
                return;
            }

            GUILayoutEx.BeginContents();
            if (!string.IsNullOrEmpty(cache.Error))
            {
                Color color = GUI.color;
                GUI.color = Color.red;
                string text = string.Format("{0}: {1}", assetid, cache.Error);
                EditorGUILayout.LabelField(text, new GUILayoutOption[0]);
                GUI.color = color;
            }
            else
            {
                string text2 = string.Format("{0} (used: {1})", assetid, cache.ReferenceCount);
                EditorGUILayout.LabelField(text2, new GUILayoutOption[0]);
                if (cache.ReferenceCount <= 0)
                {
                    float num = Time.realtimeSinceStartup - cache.LastFreeTime;
                    float num2 = cache.ReleaseAfterFree - num;
                    float value = num2 / cache.ReleaseAfterFree;
                    string text3 = string.Format("Left Sweep Time: {0:N2}", num2);
                    GUILayoutEx.ProgressBar(value, text3);
                }
            }
            GUILayoutEx.EndContents();

        }

        private void DrawTextureCacheUI()
        {
            var instance = TexturePool.Instance;
            if (this.IsFoldOut("Texture Cache", ref this.mTextureCache))
            {
                if (string.IsNullOrEmpty(this.mSearch) && instance.GetCacheAssetIDMap().Count == 0)
                {
                    EditorGUILayout.HelpBox("There is no Texture in this cache.", MessageType.Info);
                }
                foreach (var p in instance.GetCacheAssetIDMap())
                {
                    this.DrawTextureCache(p.Key, p.Value);
                }
            }
        }
        private void DrawTextureCache(AssetID assetid, TextureCache cache)
        {
            if (!this.IsSearch(assetid.BundleName) && !this.IsSearch(assetid.AssetName))
            {
                return;
            }

            GUILayoutEx.BeginContents();
            if (!string.IsNullOrEmpty(cache.Error))
            {
                Color color = GUI.color;
                GUI.color = Color.red;
                string text = string.Format("{0}: {1}", assetid, cache.Error);
                EditorGUILayout.LabelField(text, new GUILayoutOption[0]);
                GUI.color = color;
            }
            else
            {
                string text2 = string.Format("{0} (used: {1})", assetid, cache.ReferenceCount);
                EditorGUILayout.LabelField(text2, new GUILayoutOption[0]);
                if (cache.ReferenceCount <= 0)
                {
                    float num = Time.realtimeSinceStartup - cache.LastFreeTime;
                    float num2 = cache.ReleaseAfterFree - num;
                    float value = num2 / cache.ReleaseAfterFree;
                    string text3 = string.Format("Left Sweep Time: {0:N2}", num2);
                    GUILayoutEx.ProgressBar(value, text3);
                }
            }
            GUILayoutEx.EndContents();

        }

        private void DrawAudioClipCacheUI()
        {
			var instance = AudioClipPool.Instance;
			if (this.IsFoldOut("AudioClip Cache", ref this.mAudioClipCache))
			{
				if (string.IsNullOrEmpty(this.mSearch) && instance.GetCacheAssetIDMap().Count == 0)
				{
					EditorGUILayout.HelpBox("There is no AudioClip in this cache.", MessageType.Info);
				}
				foreach (var p in instance.GetCacheAssetIDMap())
				{
					this.DrawAudioClipCache(p.Key, p.Value);
				}
			}
		}
		private void DrawAudioClipCache(AssetID assetid, AudioClipCache cache)
		{
			if (!this.IsSearch(assetid.BundleName) && !this.IsSearch(assetid.AssetName))
			{
				return;
			}

			GUILayoutEx.BeginContents();
			if (!string.IsNullOrEmpty(cache.Error))
			{
				Color color = GUI.color;
				GUI.color = Color.red;
				string text = string.Format("{0}: {1}", assetid, cache.Error);
				EditorGUILayout.LabelField(text, new GUILayoutOption[0]);
				GUI.color = color;
			}
			else
			{
				string text2 = string.Format("{0} (used: {1})", assetid, cache.ReferenceCount);
				EditorGUILayout.LabelField(text2, new GUILayoutOption[0]);
				if (cache.ReferenceCount <= 0)
				{
					float num = Time.realtimeSinceStartup - cache.LastFreeTime;
					float num2 = cache.ReleaseAfterFree - num;
					float value = num2 / cache.ReleaseAfterFree;
					string text3 = string.Format("Left Sweep Time: {0:N2}", num2);
					GUILayoutEx.ProgressBar(value, text3);
				}
			}
			GUILayoutEx.EndContents();

		}

		private void Update()
		{
			if (Application.isPlaying)
			{
				this.Repaint();
			}
		}


	}
}
